import { PixelPoint, RenderTask } from "./commonTypes"

/**
 * 初始任务列表
 * @param ctx 
 * @param width 
 * @param height 
 * @param amount // 任务数量
 */
export function initTasks(
  width: number,
  height: number,
  amount: number
) {
  console.time('task')

  // 每个任务的像素数量
  const pxielAmount = width * height
  const len = Math.ceil(pxielAmount / amount)

  // 初始化全部像素点
  const pixels: PixelPoint[][] = []
  for (let y = 0; y < height; y++) {
    pixels.push([])
    for (let x = 0; x < width; x++) {
      const px = new PixelPoint(x, y)
      pixels[y].push(px)
    }
  }

  // 建立一个渲染任务
  const result: RenderTask[] = []
  let task = new RenderTask([], width, height)

  // 遍历分派全部的像素点
  while (pixels.length) {
    // y下标，随机
    const y = Math.floor(Math.random() * (pixels.length - 0.0001))

    // x下标，随机
    const pixelsX = pixels[y]
    const x = Math.floor(Math.random() * (pixelsX.length - 0.0001))

    // 删除指定位置元素，并获得对应元素
    const pixel = pixelsX.splice(x, 1)[0]

    // 将随机元素分配到任务之中
    task.pixels.push(pixel)

    // 如果一行已经清空，则删除这一行
    if (pixelsX.length === 0) {
      pixels.splice(y, 1)
    }

    // 当像素点满足长度，或者达到最后的大小
    if (task.pixels.length >= len || pixels.length === 0) {
      // 建立新的任务
      result.push(task)
      task = new RenderTask([], width, height)
    }
  }
  console.timeEnd('task')

  return result
}

/**
 * 初始任务列表，会有层文
 * @param ctx 
 * @param width 
 * @param height 
 * @param taskCount // 任务数量
 */
export function initTasks2(
  width: number,
  height: number,
  taskCount: number
) {
  console.time('task2')
  // 每个任务的像素数量，上取整确保数量足够
  const pxielAmount = width * height
  const len = Math.ceil(pxielAmount / taskCount)

  // 建立全部的任务
  const result: RenderTask[] = []
  for (let i = 0; i < taskCount; i++) {
    result.push(new RenderTask([], width, height))
  }
  // 随机初始化全部像素点
  const tmpTasks: RenderTask[] = []
  tmpTasks.push(...result)
  for (let y = 0; y < height; y++) {
    for (let x = 0; x < width; x++) {
      // 随机找到一个任务
      const taskIndex = Math.floor(Math.random() * (tmpTasks.length - 0.0001))
      // 为任务分配当前像素
      tmpTasks[taskIndex].pixels.push(new PixelPoint(x, y))
      // 如果任务已经满了则删除任务
      if (tmpTasks[taskIndex].pixels.length >= len) {
        tmpTasks.splice(taskIndex, 1)
      }
    }
  }
  console.timeEnd('task2')
  return result
}

/**
 * 初始任务列表，ai 建议的，效率最高
 * @param width 
 * @param height 
 * @param taskCount 
 * @returns 
 */
export function initTasks3(
  width: number,
  height: number,
  taskCount: number
) {
  console.time('task3')

  // 初始化全部像素
  const pixels: PixelPoint[][] = []
  for (let y = 0; y < height; y++) {
    pixels.push([])
    for (let x = 0; x < width; x++) {
      const px = new PixelPoint(x, y)
      pixels[y].push(px)
    }
  }

  // 扁平化二维数组
  let flatArray = pixels.flat();

  // 随机打乱数组
  for (let i = flatArray.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [flatArray[i], flatArray[j]] = [flatArray[j], flatArray[i]];
  }

  // 分配到 4 个不同的任务数组
  const result: RenderTask[] = []
  for (let i = 0; i < taskCount; i++) {
    result.push(new RenderTask([], width, height))
  }
  let index = 0;
  for (let item of flatArray) {
    result[index].pixels.push(item);
    index = (index + 1) % result.length;
  }
  console.timeEnd('task3')

  return result;
}


/**
 * 初始任务列表，ai 建议的，效率最高
 * @param width 
 * @param height 
 * @param taskCount 
 * @returns 
 */
export function initTasks4(
  width: number,
  height: number,
  taskCount: number
) {
  console.time('task4')

  // 分配到 4 个不同的任务数组
  const result: RenderTask[] = []
  for (let i = 0; i < taskCount; i++) {
    result.push(new RenderTask([], width, height))
  }

  // 初始化全部像素
  const pixels: PixelPoint[][] = []
  let index = 0;
  for (let y = 0; y < height; y++) {
    pixels.push([])
    for (let x = 0; x < width; x++) {
      const px = new PixelPoint(x, y)
      pixels[y].push(px)
      result[index].pixels.push(px);
      index = (index + 1) % result.length;
    }
  }

  console.timeEnd('task4')

  return result;
}